package org.bt.forecast.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.bt.common.utils.RedisUtil;
import org.bt.forecast.entity.Dlt;
import org.bt.forecast.mapper.DltMapper;
import org.bt.forecast.utils.Constant;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class DltService extends ServiceImpl<DltMapper, Dlt> {

    @Autowired
    private RedisUtil redisUtil;

    //更新大乐透
    public void updateDlt() {
        Elements elements = Jsoup.parse(HttpUtil.get(Constant.dltApi)).select("tr[class=t_tr1]");
        elements.remove(0);
        String newestId = elements.get(0).select("td[class=t_tr1]").get(0).text();
        if (!StrUtil.equals((String) redisUtil.get("dltId"), newestId)) {
            redisUtil.set("dltId", newestId);
            HashSet<String> idHashSet = new HashSet<>();
            for (Dlt dlt : baseMapper.selectList(null)) {
                idHashSet.add(dlt.getId());
            }
            List<Dlt> newDltList = new ArrayList<>();
            for (Element element : elements) {
                String id = element.select("td[class=t_tr1]").get(0).text();
                if (!idHashSet.contains(id)) {
                    Elements redElements = element.select("td[class=cfont2]");
                    Elements blueElements = element.select("td[class=cfont4]");
                    String red1 = redElements.get(0).text();
                    String red2 = redElements.get(1).text();
                    String red3 = redElements.get(2).text();
                    String red4 = redElements.get(3).text();
                    String red5 = redElements.get(4).text();
                    String blue1 = blueElements.get(0).text();
                    String blue2 = blueElements.get(1).text();
                    newDltList.add(new Dlt(id, red1, red2, red3, red4, red5, blue1, blue2));
                } else {
                    break;
                }
            }
            for (Dlt dlt : newDltList) {
                baseMapper.insert(dlt);
            }
        }
    }

    //大乐透最新一期号码
    public Dlt getNewest() {
        String newestId = redisUtil.get("dltId").toString();
        Dlt dlt = new Dlt();
        Object dltNewest = redisUtil.get("dltNewest");
        if (BeanUtil.isNotEmpty(dltNewest)) {
            dlt = JSONUtil.toBean(dltNewest.toString(), Dlt.class);
        }
        if (BeanUtil.isEmpty(dlt) || !StrUtil.equals(newestId, dlt.getId())) {
            dlt = baseMapper.selectById(newestId);
            redisUtil.set("dltNewest", dlt);
        }
        return dlt;
    }

    //大乐透选号
    public List<Dlt> get() {
        List<Dlt> dltList = new ArrayList<>();
        List<String> redList = Constant.getList("dlt", "red", sortRed());
        List<String> blueList = Constant.getList("dlt", "blue", sortBlue());
        for (int i = 0; i < 5; i++) {
            dltList.add(random(redList, blueList));
        }
        return dltList;
    }

    //红球排序
    public List<String> sortRed() {
        List<String> redList = new ArrayList<>();
        String key = "dltRedList" + redisUtil.get("dltId");
        List<String> list = Constant.castList(redisUtil.get(key), String.class);
        if (BeanUtil.isEmpty(list)) {
            List<Dlt> dltList = baseMapper.selectList(null);
            Map<String, Integer> map = new HashMap<>();
            for (int i = 1; i <= 35; i++) {
                String number = i < 10 ? "0" + i : String.valueOf(i);
                map.put(number,
                        (int) dltList.stream().filter(s -> s.getRed1().equals(number) || s.getRed2().equals(number) || s.getRed3().equals(number) || s.getRed4().equals(number) || s.getRed5().equals(number)).count());
            }
            for (Map.Entry<String, Integer> entry : MapUtil.sortByValue(map, false).entrySet()) {
                redList.add(entry.getKey());
            }
            redisUtil.set(key, redList);
        } else {
            redList.addAll(list);
        }
        return redList;
    }

    //蓝球排序
    public List<String> sortBlue() {
        List<String> blueList = new ArrayList<>();
        String key = "dltBlueList" + redisUtil.get("dlt");
        List<String> list = Constant.castList(redisUtil.get(key), String.class);
        if (BeanUtil.isEmpty(list)) {
            List<Dlt> dltList = baseMapper.selectList(null);
            Map<String, Integer> map = new HashMap<>();
            for (int i = 1; i <= 12; i++) {
                String number = i < 10 ? "0" + i : String.valueOf(i);
                map.put(number, (int) dltList.stream().filter(s -> s.getBlue1().equals(number) || s.getBlue2().equals(number)).count());
            }
            for (Map.Entry<String, Integer> entry : MapUtil.sortByValue(map, false).entrySet()) {
                blueList.add(entry.getKey());
            }
            redisUtil.set(key, blueList);
        } else {
            blueList.addAll(list);
        }
        return blueList;
    }

    //随机选号
    public Dlt random(List<String> redList, List<String> blueList) {
        List<String> list = new ArrayList<>();
        for (int j = 0; j < 5; j++) {
            int number = RandomUtil.randomInt(0, redList.size() - 1);
            while (list.contains(redList.get(number))) {
                number = RandomUtil.randomInt(0, redList.size() - 1);
            }
            list.add(redList.get(number));
        }
        List<String> tempList = new ArrayList<>();
        for (int j = 0; j < 2; j++) {
            int number = RandomUtil.randomInt(0, blueList.size() - 1);
            while (tempList.contains(blueList.get(number))) {
                number = RandomUtil.randomInt(0, blueList.size() - 1);
            }
            tempList.add(blueList.get(number));
        }
        list = ListUtil.sortByPinyin(list);
        tempList = ListUtil.sortByPinyin(tempList);
        return new Dlt("", list.get(0), list.get(1), list.get(2), list.get(3), list.get(4), tempList.get(0), tempList.get(1));
    }
}
